#library('BubbleDrawer');
#import('dart:html');
#import('Colors.dart');
#import('Bubble.dart');
#import('BubbleGrid.dart');

/** Responsible for the visual display of the game. */
class BubbleDrawer {

  // The grid of bubbles which this class draws, outlines etc.
  BubbleGrid grid;
  
  // Constructor
  BubbleDrawer(BubbleGrid this.grid);

  // Draw the given grid of bubbles and show the user's total number of points.
  void drawGame() {
    
    document.query("#game").innerHTML = getHtmlDisplay();
    document.query("#totalPoints").innerHTML = grid.totalPoints.toString();
    
    // Be sure that the 'game over' and 'number of points to gain' messages
    // are hidden whenever the grid is rendered
    document.query("#gameOver").style.display = "none";
    document.query("#selectPoints").style.visibility= "hidden";
  }
  
  // Build an html string of <img> and <br> tags for displaying the bubbles.
  String getHtmlDisplay() {
    List<Bubble> bubbles = grid.bubbles;
    int length = grid.length;
    int height = grid.height;
    
    String html = "";
    for (int j=0; j < height ; j++) {
      for (int k=0; k < length ; k++) {
        int index = j * length + k;
        html = html + "<image style='padding:$whitePadding' id='bubbles[$index]' src='${Colors.getSrc(bubbles[index].color)}'/>"; 
      }
      html = html + "</br>";
    }
    return html;
  }

  
  // Unselected bubble images use the white padding.
  String whitePadding = "1px";

  // The selected group is outlined with the black border instead.
  String blackBorder = "1px dashed black";

  // Outline the selected group of bubbles if the given boolean parameter is true.
  // Otherwise, remove the outline of the currently selected group of bubbles.
  void outlineSelectedGroup(bool outline, List<int> selected) {

    String padding = whitePadding;
    String border = "";
  
    if (outline) {
      padding = "";
      border = blackBorder;
    }
  
    // For each selected bubble, either outline the side of the border facing a not selected bubble by replacing
    // the padding with a black border or remove the outline by removing the black border and adding the padding.
    for (int index in selected) {
      Element image = getBubbleImage(index);
      if (selected.indexOf(index + 1) < 0 ) {
        image.style.borderRight = border;
        image.style.paddingRight = padding;
        }
      if (selected.indexOf(index - 1 ) < 0) {
        image.style.borderLeft = border;
        image.style.paddingLeft = padding;
        }
      if (selected.indexOf(index - grid.length) < 0 ) {
        image.style.borderTop = border;
        image.style.paddingTop = padding;
        }
      if (selected.indexOf(index + grid.length) < 0) {
        image.style.borderBottom = border;
        image.style.paddingBottom = padding;
        }
      }
  }

  // Display text when game is over.
  void alertGameOver(int points) {
    document.query("#gameOver").style.display = "";
    document.query("#totalPoints").innerHTML = points.toString();
    window.location='#gameOver';
  }

  // Get the image tag corresponding to the bubble at the given index.
  Element getBubbleImage(int index) {
    String id = "bubbles[$index]";
    List<Element> images = document.queryAll('img');
    for (Element e in images) {
      if (e.id == id) {
       return e;
      }
    }
  }
  
  // Hides/shows the number of points a user can gain by removing the selected group
  // of bubbles.
  void hideSelectedPoints(bool hide) {
    if (hide) {
      document.query("#selectPoints").style.visibility= "hidden";
    }
    else {
      document.query("#selectPoints").style.visibility= "";
    }
  }
  
  // Sets the number of points a user can gain by removing the selected group of
  // bubbles.
  void setSelectPoints(int points) {
    document.query("#groupPoints").innerHTML = points.toString();
  }

}
